package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.constant.BspsAppParamConstant;
import cc.rengu.igas.bsps.common.dao.*;
import cc.rengu.igas.bsps.common.dao.impl.*;
import cc.rengu.igas.bsps.common.entity.*;
import cc.rengu.igas.bsps.common.enums.*;
import cc.rengu.igas.bsps.core.model.UserSessionInfo;
import cc.rengu.igas.bsps.core.service.base.ManageService;
import cc.rengu.igas.bsps.facade.base.Header;
import cc.rengu.igas.bsps.facade.bean.MchntBindInfoBean;
import cc.rengu.igas.bsps.facade.bean.PrivilegeInfoBean;
import cc.rengu.igas.bsps.facade.request.MobileBankAuthLoginRequest;
import cc.rengu.igas.bsps.facade.response.MobileBankAuthLoginResponse;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zhangxuran
 * @version 1.0
 * @date 2020/04/10
 */
public class MobileBankAuthLoginService extends ManageService {
    @Override
    protected Object bizBeforeCust() throws Exception {
        MobileBankAuthLoginRequest mobileBankAuthLoginRequest = new MobileBankAuthLoginRequest();
        ConvertUtil.convertOutput(mobileBankAuthLoginRequest);
        return mobileBankAuthLoginRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        MobileBankAuthLoginRequest mobileBankAuthLoginRequest = (MobileBankAuthLoginRequest) request;
        /*获取请求参数信息：法人行，设备唯一标识，手机银行账号*/
        String instId = mobileBankAuthLoginRequest.getHeader().getInstId();
        String devUniqueId = mobileBankAuthLoginRequest.getDevUniqueId();
        Header header = mobileBankAuthLoginRequest.getHeader();
        String channel = header.getChanlId();
        if (StringUtil.isEmptyOrNull(devUniqueId) || StringUtil.isEmptyOrNull(instId)) {
            rglog.error("手机银行认证登录必填性校验失败!");
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }
        /*根据设备唯一标识查询设备绑定表中是否绑定用户*/
        BspsDevBindInfoMapper bspsDevBindInfoMapper = new BspsDevBindInfoMapperImpl();
        DevBindInfo devBindInfo = bspsDevBindInfoMapper.selectBspsDevBindInfoByDevUniqueIdAndDevType(instId, devUniqueId, BindDevEnum.PHONE_DEV.getDevCode(), "00");
        if (null == devBindInfo) {
            rglog.error("设备未绑定商户收银员!");
            throw new BizException(RespCodeEnum.GET_DEVBINDINFO_ERROR.getRespCode(), RespCodeEnum.GET_DEVBINDINFO_ERROR.getRespDesc());
        }
        /*根据设备绑定收银员信息查询用户信息：目前业务中收银员信息和openId是一一对应，此时只对应一个商户号，如果后期业务调整为一个openId与收银员信息是一对多后，手机银行绑定需增加商户选择部分功能*/
        BspsUserInfoMapper bspsUserInfoMapper = new BspsUserInfoMapperImpl();
        UserInfo userInfo = bspsUserInfoMapper.selectBspsUserInfoByUserId(instId, devBindInfo.getBindUserId());
        if (null == userInfo) {
            rglog.error("用户信息查询失败!");
            throw new BizException(RespCodeEnum.GET_USER_INFO_ERROR.getRespCode(), RespCodeEnum.GET_USER_INFO_ERROR.getRespDesc());
        }
        /*查询绑定商户状态*/
        BspsMchntBaseInfoMapper bspsMchntBaseInfoMapper = new BspsMchntBaseInfoMapperImpl();
        MchntBaseInfo mchntBaseInfo = bspsMchntBaseInfoMapper.selectBspsMchntBaseInfoByPrimaryKey(instId, devBindInfo.getBindMchntNo());
        /*判断商户状态*/
        if (null == mchntBaseInfo) {
            rglog.error("商户基本信息查询失败!");
            throw new BizException(RespCodeEnum.QUERY_MCHNT_BASE_INFO_ERROR.getRespCode(), RespCodeEnum.QUERY_MCHNT_BASE_INFO_ERROR.getRespDesc());
        }
        /*判断商户状态*/
        if (!MchntStatusEnum.NORMAL.getStatus().equals(mchntBaseInfo.getMchntStatus())) {
            rglog.error("商户状态异常!");
            throw new BizException(RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespCode(), RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespDesc());
        }
        /*查询商户绑定信息表*/
        BspsMchntBindInfoMapper bspsMchntBindInfoMapper = new BspsMchntBindInfoMapperImpl();
        MchntBindInfo mchntBindInfo = bspsMchntBindInfoMapper.selectBspsMchntBindInfoListByUserIdAndMchntNo(instId, devBindInfo.getBindUserId(), devBindInfo.getBindMchntNo());
        /*判断商户绑定状态*/
        if (null == mchntBindInfo) {
            rglog.error("查询用户绑定商户信息失败!");
            throw new BizException(RespCodeEnum.GET_USER_BIND_INFO_ERROR.getRespCode(), RespCodeEnum.GET_USER_BIND_INFO_ERROR.getRespDesc());
        }
        if (!BindStatusEnum.BIND.getStatus().equals(mchntBindInfo.getBindStatus())) {
            rglog.error("用户绑定商户状态异常");
            throw new BizException(RespCodeEnum.BIND_MCHNT_STATUS_ERROR.getRespCode(), RespCodeEnum.BIND_MCHNT_STATUS_ERROR.getRespDesc());
        }
        /*登记商户登录信息表*/
        /*根据用户绑定商户角色查询权限*/
        BspsUserRoleInfoMapper bspsUserRoleInfoMapper = new BspsUserRoleInfoMapperImpl();
        List<UserRoleInfo> userRoleInfoList = bspsUserRoleInfoMapper.selectBspsUserRoleInfoToChannelMenu(instId, mchntBindInfo.getBindUserRole(), channel);
        /*角色权限赋值*/
        List<PrivilegeInfoBean> privilegeInfoList = new ArrayList<>();
        if (null != userRoleInfoList && !userRoleInfoList.isEmpty()) {
            userRoleInfoList.forEach(item -> convUserRoleInfo(item, privilegeInfoList));
        }
        /*新增用户登录信息*/
        BspsUserLoginInfoMapper bspsUserLoginInfoMapper = new BspsUserLoginInfoMapperImpl();
        UserLoginInfo userLoginInfo = new UserLoginInfo();
        /*法人行赋值*/
        userLoginInfo.setInstId(instId);
        /*登录方式赋值*/
        userLoginInfo.setLoginType(BspsLoginTypeEnum.OPEN_ID.getLoginType());
        /*用户标识赋值*/
        userLoginInfo.setUserId(userInfo.getUserId());
        /*登录时间赋值*/
        userLoginInfo.setLoginTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        /*最后操作时间赋值*/
        userLoginInfo.setLastOprTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        /*登录状态赋值*/
        userLoginInfo.setLoginStatus("0");
        /*session赋值*/
        userLoginInfo.setSessionId(mobileBankAuthLoginRequest.getHeader().getSession());

        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.OLTP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.OLTP_POOL_NAME);
        }
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();
        /*新增用户登录信息*/
        int iReturnCode = bspsUserLoginInfoMapper.insertBspsUserLoginInfo(userLoginInfo);
        if (0 != iReturnCode) {
            dbsUtil.dbsEndTransaction(false);
            rglog.error("用户登录信息新增失败！");
            throw new BizException(RespCodeEnum.REGISTER_USER_LOGIN_INFO_ERROR.getRespCode(), RespCodeEnum.REGISTER_USER_LOGIN_INFO_ERROR.getRespDesc());
        }
        dbsUtil.dbsEndTransaction(true);
        /*将用户信息放入redis缓存中*/
        UserSessionInfo keySessionInfo = JSON.parseObject(RedisUtil.onceGet(header.getSession()), UserSessionInfo.class);
        keySessionInfo.setUserId(userInfo.getUserId());
        RedisUtil.onceSet(header.getSession(), JSONObject.toJSONString(keySessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);

        String newSessionId = RandomUtil.getUUID();
        UserSessionInfo userSessionInfo = new UserSessionInfo();
        userSessionInfo.setUserId(userInfo.getUserId());
        userSessionInfo.setSignatureKey(keySessionInfo.getSignatureKey());
        userSessionInfo.setSensitiveKey(keySessionInfo.getSensitiveKey());
        RedisUtil.onceSet(newSessionId, JSONObject.toJSONString(userSessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);
        header.setSession(newSessionId);

        /*组装返回报文*/
        MchntBindInfoBean mchntBindInfoBean = new MchntBindInfoBean();
        /*商户名赋值*/
        mchntBindInfoBean.setMchntName(mchntBaseInfo.getMchntName());
        /*商户号赋值*/
        mchntBindInfoBean.setMchntNo(mchntBaseInfo.getMchntNo());
        /*连锁商户号赋值*/
        mchntBindInfoBean.setChainMchntNo(mchntBaseInfo.getChainMchntNo());
        /*绑定状态赋值*/
        mchntBindInfoBean.setBindStatus(mchntBindInfo.getBindStatus());
        /*绑定时间赋值*/
        mchntBindInfoBean.setBindTime(mchntBindInfo.getBindDate() + " " + mchntBindInfo.getBindTime());
        /*绑定角色赋值*/
        mchntBindInfoBean.setBindUserRole(mchntBindInfo.getBindUserRole());
        /*用户角色权限赋值*/
        mchntBindInfoBean.setPrivilegeInfoBeanList(privilegeInfoList);
        /*退款权限-法人、店长都有权限,白名单的收银员有权限*/
        if (((BspsUserRoleTypeEnum.MCHNT_ARTIF.getRoleType().equals(mchntBindInfo.getBindUserRole()))
                || (BspsUserRoleTypeEnum.MCHNT_MANAGER.getRoleType().equals(mchntBindInfo.getBindUserRole())))) {
            rglog.info("法人、店长登录");
            //有退款权限
            mchntBindInfoBean.setRefundFlag(AppParamConstant.YES);
        } else {
            rglog.info("非法人、店长登录");
            //校验白名单收银员退款权限,null/NO为无权限
            SysParamService sysParamService = new SysParamServiceImpl();
            SysParam sysParam = sysParamService.getSysParamInfo(instId, BspsAppParamConstant.BSPS_REFUND_MERCH, mchntBindInfo.getMchntNo());
            if (sysParam == null) {
                rglog.info("非白名单商户");
                mchntBindInfoBean.setRefundFlag(AppParamConstant.NO);
            } else if (AppParamConstant.YES.equals(sysParam.getParamValue())) {
                rglog.info("白名单商户");
                mchntBindInfoBean.setRefundFlag(AppParamConstant.YES);
            } else {
                rglog.info("非白名单商户");
                mchntBindInfoBean.setRefundFlag(AppParamConstant.NO);
            }
        }
        List<MchntBindInfoBean> mchntBindInfoList = new ArrayList<>();
        mchntBindInfoList.add(mchntBindInfoBean);

        MobileBankAuthLoginResponse mobileBankAuthLoginResponse = new MobileBankAuthLoginResponse();
        mobileBankAuthLoginResponse.setHeader(header);
        /*昵称赋值*/
        mobileBankAuthLoginResponse.setNickName(userInfo.getNickName());
        /*性别赋值*/
        mobileBankAuthLoginResponse.setUserSex(userInfo.getUserSex());
        /*邮箱赋值*/
        mobileBankAuthLoginResponse.setEmail(userInfo.getEmail());
        /*头像赋值*/
        mobileBankAuthLoginResponse.setUserImagePath(userInfo.getUserImagePath());
        mobileBankAuthLoginResponse.setMsgPushFlag(devBindInfo.getMsgPushFlag());
        mobileBankAuthLoginResponse.setUserId(userInfo.getUserId());
        mobileBankAuthLoginResponse.setUserLoginId(userInfo.getUserLoginId());
        /**/
        mobileBankAuthLoginResponse.setMchntBindInfoBeanList(mchntBindInfoList);
        /* 按照接口转换基础产品信息并响应给请求方 */
        BizResponse<MobileBankAuthLoginResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(mobileBankAuthLoginResponse);
        return bizResponse;
    }

    /**
     * 用户权限信息装换、
     * userRoleInfo 用户权限信息
     **/
    private void convUserRoleInfo(UserRoleInfo userRoleInfo, List<PrivilegeInfoBean> privilegeInfoList) {
        PrivilegeInfoBean privilegeInfo = new PrivilegeInfoBean();
        /*菜单标识赋值*/
        privilegeInfo.setMenuId(userRoleInfo.getMenuId());
        /*菜单名称赋值*/
        privilegeInfo.setMenuName(userRoleInfo.getMenuName());
        /*功能权限标识*/
        privilegeInfo.setFuncDroitId(userRoleInfo.getFuncDroitId());
        /*功能权限名称赋值*/
        privilegeInfo.setFuncDroitDesc(userRoleInfo.getFuncDroitDesc());
        /*菜单页面路径赋值*/
        privilegeInfo.setMenuUrlPath(userRoleInfo.getMenuUrlPath());
        /* 上级菜单 */
        privilegeInfo.setSuperMenuId(userRoleInfo.getSuperMenuId());
        /* 菜单是否隐藏标识 */
        privilegeInfo.setMenuHideFlag(userRoleInfo.getMenuHideFlag());
        BeanUtil.beanCopy(userRoleInfo, privilegeInfo);
        privilegeInfoList.add(privilegeInfo);
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        MobileBankAuthLoginResponse mobileBankAuthLoginResponse = (MobileBankAuthLoginResponse) bizResponse.getResult();
        ConvertUtil.convertInput(mobileBankAuthLoginResponse);
    }
}
